<?php


namespace App\Http\Controllers;


use App\Models\ExcelUser;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;

class ExcelController extends Controller
{
    public function loginWithPassword(Request $request)
    {
        $userName = $request->get('userName');
        $password = $request->get('password');

        if (empty($userName) || empty($password)) {
            return $this->responseJson(101, 'param error');
        }

        /** @var ExcelUser $exUser */
        $exUser = ExcelUser::query()->where('user_name', $userName)
            ->first();

        if (empty($exUser)) {
            return $this->responseJson(102, 'user not exist');
        }

        $password = md5($password . $exUser->salt);

        if ($exUser->password != $password) {
            return $this->responseJson(103, 'password error');
        }

        return $this->responseJson(200, 'success', ['college' => $exUser->college])
            ->cookie("login-token", $exUser->id, 3600, '', null, null, false);
    }

    public function upload(Request $request)
    {
        if (empty($request->cookie('login-token'))) {
            return $this->responseJson(100, 'please login');
        }

        $uid = $request->cookie('login-token');

        if (!$request->hasFile('excel')) {
            return $this->responseJson(101, 'excel not exist');
        }

        /** @var ExcelUser $user */
        $user = ExcelUser::query()
            ->where('id', intval($uid))
            ->first();

        if (empty($user)) {
            return $this->responseJson(102, 'user not exist')->cookie("login-token", 0, -1);
        }

        $file = $request->file('excel');

        $res = $file->storeAs('excel/' . $user->id, $file->getClientOriginalName());

        if (empty($res)) {
            return $this->responseJson(103, 'save file error');
        }

        $excel = \App\Models\Excel::query()->where('excel_user_id', $user->id)
            ->where('file_name', $file->getClientOriginalName())
            ->first();

        if ($excel) {
            $excel->lastUploadAt = date('Y-m-d H:i:s');
            $excel->noDiff       = 0;
            $excel->save();
            return $this->responseJson(200);
        }


        $e                = new \App\Models\Excel();
        $e->path          = storage_path('app/excel/' . $user->id);
        $e->file_name     = $file->getClientOriginalName();
        $e->excel_user_id = $user->id;
        $res              = $e->save();

        if (empty($res)) {
            return $this->responseJson(104, 'save record error');
        }

        return $this->responseJson(200);
    }

    public function excelList(Request $request)
    {
        if (empty($request->cookie('login-token'))) {
            return $this->responseJson(100, 'please login');
        }

        $uid = $request->cookie('login-token');

        /** @var ExcelUser $user */
        $user = ExcelUser::query()
            ->where('id', intval($uid))
            ->first();

        if (empty($user)) {
            return $this->responseJson(102, 'user not exist')->cookie("login-token", 0, -1);
        }

        /** @var ExcelUser $user */
        $otherUser = ExcelUser::query()
            ->where('college', $user->college)
            ->where('id', '!=', $user->id)
            ->first();

        /** @var \App\Models\Excel[] $allFiles */
        $allFiles = \App\Models\Excel::query()->whereIn('excel_user_id', [$uid, $otherUser ? $otherUser->id : 0])
            ->get();

        $data = [
            'me'        => $user->user_name,
            'otherUser' => $otherUser ? $otherUser->user_name : '未知',
            'list'      => [],
            'college'   => $user->college,
        ];

        foreach ($allFiles as $allFileA) {
            if ($allFileA->excel_user_id != $uid) {
                continue;
            }

            $data['list'][$allFileA->file_name]                       = [];
            $data['list'][$allFileA->file_name]['myFileID']           = $allFileA->id;
            $data['list'][$allFileA->file_name]['fileName']           = $allFileA->file_name;
            $data['list'][$allFileA->file_name]['myFileLastUploadAt'] = $allFileA->lastUploadAt;
            $data['list'][$allFileA->file_name]['otherUserFileID']    = 0;
            $data['list'][$allFileA->file_name]['noDiff']             = 0;

            foreach ($allFiles as $allFileB) {
                if ($allFileB->file_name != $allFileA->file_name || $allFileB->excel_user_id == $uid) {
                    continue;
                }

                $data['list'][$allFileA->file_name]['otherUserFileID']           = $allFileB->id;
                $data['list'][$allFileA->file_name]['otherUserFileLastUploadAt'] = $allFileB->lastUploadAt;
                $data['list'][$allFileA->file_name]['noDiff']                    = $allFileA->noDIff && $allFileB->noDIff;
            }
        }

        $data['list'] = array_values($data['list']);

        return $this->responseJson(200, 'success', $data);
    }

    public function uploadExcel(Request $request)
    {
        if (empty($request->cookie('login-token'))) {
            return $this->responseJson(100, 'please login');
        }

        $excelA = $request->post('excelAID');
        $excelB = $request->post('excelBID');

        if (empty($excelA) || empty($excelB)) {
            return $this->responseJson(101, 'param error');
        }

        /** @var \App\Models\Excel[] $files */
        $files = \App\Models\Excel::query()
            ->whereIn('id', [$excelA, $excelB])
            ->get();

        if (empty($files) || count($files) < 2) {
            return $this->responseJson(102, 'file not exist');
        }
        $excelAPath = '';
        $excelBPath = '';

        foreach ($files as $file) {
            if ($file->id == $excelA) {
                $excelAPath = $file->path . '/' . $file->file_name;
            }

            if ($file->id == $excelB) {
                $excelBPath = $file->path . '/' . $file->file_name;
            }
        }

        $excelAModel = new \App\Models\ExcelData();

        Excel::import($excelAModel, $excelAPath);

        $excelBModel = new \App\Models\ExcelData();

        Excel::import($excelBModel, $excelBPath);

        if (empty($excelAModel->arr)) {
            return $this->responseJson(102, 'parse excelA fail');
        }

        if (empty($excelBModel->arr)) {
            return $this->responseJson(102, 'parse excelB fail');
        }

        $a = $excelAModel->arr;
        $b = $excelBModel->arr;

        $res     = [];
        $allDiff = [];

        foreach ($a as $ak => $av) {
            foreach ($b as $bk => $bv) {
                if ($ak != $bk) {
                    continue;
                }

                [$t, $d] = $this->diff($ak, $av, $bv);
                $res[] = $t;

                if ($d) {
                    $allDiff = array_merge($allDiff, $d);
                }
            }
        }

        if (empty($allDiff)) {
            foreach ($files as $file) {
                $file->noDIff = 1;
                $file->save();
            }

            $e = \PHPExcel_IOFactory::load($file->path());
            $a = $e->setActiveSheetIndex(0);
            $a->getCell('A1')->setValue('嘉兴南洋职业技术学院提前招生测试成绩登记表');

            $j = 0;
            while (1) {
                $j++;

                if ($j <= 4) {
                    continue;
                }

                $name = $a->getCell('A' . $j)->getValue();
                if (empty($name)) {
                    break;
                }

                $d1 = $a->getCell('B' . $j)->getValue();
                $d2 = $a->getCell('C' . $j)->getValue();
                $d3 = $a->getCell('D' . $j)->getValue();
                $d4 = $a->getCell('E' . $j)->getValue();
                $d5 = $a->getCell('F' . $j)->getValue();
                $d  = $a->getCell('G' . $j);

                $flag = true;

                for ($i = 1; $i < 5; $i++) {
                    $vName = 'd' . $i;
                    var_dump($$vName);
                    if ($$vName !== null) {
                        $flag = false;
                    }
                }

                if ($flag) {
                    $d->setValue('缺考');
                }
            }

            $w    = \PHPExcel_IOFactory::createWriter($e, 'Excel2007');
            $path = 'ex/' . uniqid() . 'xlsx';

            $w->save(storage_path($path));

            return response()->download($path, $files[0]->file_name, [
                'Content-Type'              => 'application/vnd.ms-execl',
                'Content-Transfer-Encoding' => 'binary',
                'Cache-Control: max-age=0',
            ]);
        }

        return $this->responseJson(200, 'success', ['table' => $res, 'allDiff' => $allDiff]);
    }

    private function makeRows()
    {
        $rows = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';

        $rows = explode(',', $rows);

        $new = [];
        foreach ($rows as $row) {
            $new[] = $row;
        }

        foreach ($rows as $a) {
            foreach ($rows as $b) {
                $new[] = $a . $b;
            }
        }

        return $new;
    }

    private function diff(int $y, $av, $bv)
    {
        $rows = $this->makeRows();

        $res     = [];
        $allDiff = [];
        foreach ($av as $x1 => $a) {
            foreach ($bv as $x2 => $b) {
                if ($x1 != $x2) {
                    continue;
                }

                $res[$rows[$x1]] = [
                    'x' => $rows[$x1],
                    'a' => $a,
                    'b' => $b,
                ];

                $res[$rows[$x1]]['diff'] = $a != $b;

                if ($a != $b) {
                    $allDiff[] = ['x' => $rows[$x1], 'y' => $y + 1];
                }
            }
        }

        return [array_values($res), $allDiff];
    }

    public function checkLogin(Request $request)
    {
        if (empty($request->cookie('login-token'))) {
            return $this->responseJson(100, 'please login');
        }

        return $this->responseJson(200, '');
    }
}
